﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Collections;
using System.Drawing.Text;
using System.Configuration;
using System.Media;
using WMPLib;

namespace MyGame2
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        #region 定义自定义游戏数据类型枚举
        public enum MineGame
        {
            RedFlag,                            //红旗
            Mine,                               //地雷
            Empty,                              //空白
            Doubt,                              //问号
            Explode,
            Zero,                               //0
            One,
            Two,
            Three,
            Four,
            Five,
            Six,
            Seven,
            Eight
        }
        #endregion

        #region 属性
        private int box = 0;                      //方块大小
        private int time = 0;                     //游戏时间
        private int someX = 0;                    //X轴坐标
        private int someY = 0;                    //Y轴坐标
        private int lastOverX = -1;               //最后移动的X轴
        private int lastOverY = -1;               //最后移动的Y轴
        private int mineCount = 0;                //地雷个数
        private int blankCount = 0;               //空白个数

        private bool playSound = true;            //是否播放声音
        private bool isQuestion = true;           //是否允许问号
        private bool isFristPaly = true;          //
        private bool isNewPaly = true;            //
        private bool MouseButtonsRight = false;
        private bool MouseButtonsLeft = false;
   
        private static int x = 0;                 //X轴方块个数
        private static int y = 0;                 //Y轴方块个数
        public static bool isFirstRun = true;     //是否是首次运行
        public static bool isGameOver = false;    //是否游戏已经结束
        public static string gameStartType = "0"; //游戏开始类型 0.什么都不发生 1.重新开始 2.重新开始上一次游戏

        private string[] blankCoordinate = null;

        private Color flipColor;                  //绘制的底色
        private Color backColor;                  //背景色

        ArrayList lastBoxColor = new ArrayList();
        
        //配置文件路径
        private static readonly string XmlFileName = Application.StartupPath + "\\GameConfig.xml";
        //Color.White 空白 Color.Red地雷
        private static MineGame[,] mine = null;      //记录地雷
        private static MineGame[,] gameMain = null;  //记录红旗,以及各地雷周围的数字
        //实例化资源文件类
        System.Resources.ResourceManager manager = new System.Resources.ResourceManager("MyGame2.Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
        //实例化音乐播放器
        WMPLib.WindowsMediaPlayer wmp = new WindowsMediaPlayer();
        #endregion

        #region 开始游戏
        /// <summary>
        /// 游戏开始
        /// </summary>
        public void GameStart()
        {
            ResetPage();
            BrushMine();
            DrawMine();
            if (isNewPaly)
            {
                NewGamePlay();
            }
            panelMain.Refresh();
        }
        #endregion

        #region 首次运行游戏
        /// <summary>
        /// 首次运行游戏
        /// </summary>
        public void FirstRunGame()
        {
            ReadConfig();
            ResetPage();
            BrushMine();
            DrawMine();
            if (isNewPaly)
            {
                NewGamePlay();
            }
        }
        #endregion

        #region 重新开始本次游戏
        /// <summary>
        /// 重新开始本次游戏
        /// </summary>
        public void ReGameStart()
        {
            ResetPage();
            Graphics g = panelMain.CreateGraphics();
            for (int i = 0; i < blankCoordinate.Length; i++)
            {
                string[] coordinate = blankCoordinate[i].Split(',');
                int x = int.Parse(coordinate[0]);
                int y = int.Parse(coordinate[1]);
                SetDrawString(0, x, y, g);
            }
            g.Dispose();
            panelMain.Refresh();
        }
        #endregion

        #region 在游戏区绘制小方块
        /// <summary>
        /// 画方格线的函数
        /// </summary>
        private void DrawLine()
        {
            Graphics g = panelMain.CreateGraphics();
            for (int i = 0; i <= x; i++)
            {
                g.DrawLine(new Pen(Color.Black), panelMain.Width / x * i, 0, panelMain.Width / x * i, panelMain.Height);
            }
            for (int i = 0; i <= y; i++)
            {
                g.DrawLine(new Pen(Color.Black), 0, panelMain.Height / y * i, panelMain.Width, panelMain.Height / y * i);
            }
            g.Dispose();
        }
        #endregion

        #region 初始化游戏区域,清空地雷记录
        /// <summary>
        /// 清空地雷区
        /// </summary>
        private void BrushMine()
        {
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < x; j++)
                {
                    mine[i, j] = MineGame.Empty;        //将地雷清空
                }
            }
        }
        #endregion

        #region 初始化游戏区域,清空红旗数字空白
        /// <summary>
        /// 清空游戏区
        /// </summary>
        private void BrushGameMain()
        {
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < x; j++)
                {
                    gameMain[i, j] = MineGame.Empty;    //将红旗数字清空
                }
            }
        }
        #endregion

        #region 主页绘制事件
        public void panelMain_Paint(object sender, PaintEventArgs e)
        {
            DrawLine();
            //如果是首次运行
            Graphics g = panelMain.CreateGraphics();
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;   //画出数字
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;                     //高质量显示图片
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < x; j++)
                {
                    SolidBrush sb = null;
                    int count = 0;

                    if (gameMain[i, j] == MineGame.RedFlag)
                    {
                        g.DrawImage((Bitmap)manager.GetObject("redflag"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                    }
                    else if (isGameOver)
                    {
                        if (gameMain[i, j] == MineGame.Explode)
                        {
                            g.FillRectangle(new SolidBrush(Color.Yellow), someY * j + 1, someX * i + 1, someX - 1, someY - 1);
                            g.DrawImage((Bitmap)manager.GetObject("mine"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                            g.DrawImage((Bitmap)manager.GetObject("Explode1"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                        }else
                        if (mine[i, j] == MineGame.Mine)
                        {
                            g.DrawImage((Bitmap)manager.GetObject("mine"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                        }
                    }

                    switch (gameMain[i, j])
                    {
                        case MineGame.Zero:
                            count = 0;
                            sb = new SolidBrush(Color.White);
                            break;
                        case MineGame.One:
                            count = 1;
                            sb = new SolidBrush(Color.Blue);
                            break;
                        case MineGame.Two:
                            count = 2;
                            sb = new SolidBrush(Color.Green);
                            break;
                        case MineGame.Three:
                            count = 3;
                            sb = new SolidBrush(Color.OrangeRed);
                            break;
                        case MineGame.Four:
                            count = 4;
                            sb = new SolidBrush(Color.DarkBlue);
                            break;
                        case MineGame.Five:
                            count = 5;
                            sb = new SolidBrush(Color.DarkRed);
                            break;
                        case MineGame.Six:
                            count = 6;
                            sb = new SolidBrush(Color.LawnGreen);
                            break;
                        case MineGame.Seven:
                            count = 7;
                            sb = new SolidBrush(Color.IndianRed);
                            break;
                        case MineGame.Eight:
                            count = 8;
                            sb = new SolidBrush(Color.PaleVioletRed);
                            break;
                    }
                    if (sb != null)
                    {
                        //喷绘白底
                        g.FillRectangle(new SolidBrush(Color.White), someY * j + 1, someX * i + 1, someX - 1, someY - 1);
                        g.DrawString(count.ToString(), new Font("黑体",box-5, FontStyle.Bold), sb, new PointF(box * j + 2, box * i + 1));
                    }
                }
            }
            g.Dispose();
        }
        #endregion

        #region 初始地雷分布
        /// <summary>
        /// 初始化游戏区以及地雷分布
        /// </summary>
        private void DrawMine()
        {
            //计算并随机分布地雷
            int MCX = 0;
            Random random = new Random();
            for (int i = 0; i < mineCount - MCX; i++)
            {
                int xz = random.Next(0, x - 1);
                int yz = random.Next(0, y - 1);
                if (mine[yz, xz] == MineGame.Empty)
                {
                    mine[yz, xz] = MineGame.Mine;
                }
                else
                {
                    if (i == 0)
                    {
                        i = 0;
                    }
                    else
                    {
                        i--;
                    }
                }
            }

            #region 绝对平均算法,以及测试画雷
            //for (int i = 0; i < y; i++)
            //{
            //    int lineMine = random.Next(mineCount / y - 2 < 0 ? 0 : mineCount / y - 2, mineCount / y + 2 < 0 ? 0 : mineCount / y + 2);
            //    MCX += lineMine;
            //    if (MCX > mineCount)
            //    {
            //        lineMine = mineCount - (MCX - lineMine);
            //    }
            //    //else if (i == y - 1)
            //    //{
            //    //    lineMine = mineCount - MCX;
            //    //}
            //    for (int j = 0; j < lineMine; j++)
            //    {
            //        int xx = random.Next(0, x - 1);
            //        if (mine[i, xx] == MineGame.Empty)
            //        {
            //            mine[i, xx] = MineGame.Mine;
            //        }
            //        else
            //        {
            //            if (j == 0)
            //            {
            //                j = 0;
            //            }
            //            else
            //            {
            //                j--;
            //            }
            //        }
            //        test++;
            //    }
            //}
            //Graphics g = panelMain.CreateGraphics();
            //g.InterpolationMode = InterpolationMode.HighQualityBicubic;//高质量显示图片
            //for (int i = 0; i < y; i++)
            //{
            //    for (int j = 0; j < x; j++)
            //    {
            //        if (mine[i, j] == Color.Red)
            //        {
            //            g.DrawImage((Bitmap)manager.GetObject("mine"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
            //        }
            //    }
            //}
            //g.Dispose();
            #endregion
        }
        #endregion

        #region 翻开3个空白板块
        private void NewGamePlay() 
        {
            blankCoordinate = new string[blankCount];
            Graphics g = panelMain.CreateGraphics();
            Random random = new Random();
            int blankBox = 0;
            for (int i = 0; i < x*y; i++)
            {
                int xz = random.Next(0, x - 1);
                int yz = random.Next(0, y - 1);
                if (mine[yz, xz] == MineGame.Empty && gameMain[yz, xz] == MineGame.Empty)
                {
                    if (blankBox > blankCount - 1) 
                    {
                        break;
                    }
                    if (GetMineCount(yz, xz) != 0)
                    {
                        continue;
                    }
                    blankCoordinate[blankBox] = yz + "," + xz;
                    SetDrawString(0, yz, xz, g);
                    blankBox++;
                } 
            }
            g.Dispose(); 
        }
        #endregion

        #region 单击事件
        private void panelMain_MouseClick(object sender, MouseEventArgs e)
        {
           
        }
        #endregion

        #region 计算周围8个格子总共多少雷
        /// <summary>
        /// 计算周围8个格子总共多少雷
        /// </summary>
        /// <param name="i">当前第几行</param>
        /// <param name="j">当前第几列</param>
        private int GetMineCount(int i, int j)
        {
            int count = 0;
            if (i - 1 >= 0)
            {
                if (mine[i - 1, j] == MineGame.Mine)
                {
                    count++;
                }
            }

            if (i - 1 >= 0 && j - 1 >= 0)
            {
                if (mine[i - 1, j - 1] == MineGame.Mine)
                {
                    count++;
                }
            }

            if (j - 1 >= 0)
            {
                if (mine[i, j - 1] == MineGame.Mine)
                {
                    count++;
                }
            }

            if (i + 1 < y && j - 1 >= 0)
            {
                if (mine[i + 1, j - 1] == MineGame.Mine)
                {
                    count++;
                }
            }

            if (i + 1 < y)
            {
                if (mine[i + 1, j] == MineGame.Mine)
                {
                    count++;
                }
            }

            if (i - 1 >= 0 && j + 1 < x)
            {
                if (mine[i - 1, j + 1] == MineGame.Mine)
                {
                    count++;
                }
            }

            if (j + 1 < x)
            {
                if (mine[i, j + 1] == MineGame.Mine)
                {
                    count++;
                }
            }


            if (i + 1 < y && j + 1 < x)
            {
                if (mine[i + 1, j + 1] == MineGame.Mine)
                {
                    count++;
                }
            }

            return count;
        }
        #endregion

        #region 计算周围8个格子总共多少红旗
        /// <summary>
        /// 计算周围8个格子总共多少红旗
        /// </summary>
        /// <param name="i">当前第几行</param>
        /// <param name="j">当前第几列</param>
        private int GetgameMainCount(int i, int j)
        {
            int count = 0;
            if (i - 1 >= 0)
            {
                if (gameMain[i - 1, j] == MineGame.RedFlag)
                {
                    count++;
                }
            }

            if (i - 1 >= 0 && j - 1 >= 0)
            {
                if (gameMain[i - 1, j - 1] == MineGame.RedFlag)
                {
                    count++;
                }
            }

            if (j - 1 >= 0)
            {
                if (gameMain[i, j - 1] == MineGame.RedFlag)
                {
                    count++;
                }
            }

            if (i + 1 < y && j - 1 >= 0)
            {
                if (gameMain[i + 1, j - 1] == MineGame.RedFlag)
                {
                    count++;
                }
            }

            if (i + 1 < y)
            {
                if (gameMain[i + 1, j] == MineGame.RedFlag)
                {
                    count++;
                }
            }

            if (i - 1 >= 0 && j + 1 < x)
            {
                if (gameMain[i - 1, j + 1] == MineGame.RedFlag)
                {
                    count++;
                }
            }

            if (j + 1 < x)
            {
                if (gameMain[i, j + 1] == MineGame.RedFlag)
                {
                    count++;
                }
            }


            if (i + 1 < y && j + 1 < x)
            {
                if (gameMain[i + 1, j + 1] == MineGame.RedFlag)
                {
                    count++;
                }
            }

            return count;
        }
        #endregion

        #region 计算当前方块周围
        /// <summary>
        /// 计算当前方块周围8格
        /// </summary>
        /// <param name="i">X轴</param>
        /// <param name="j">Y轴</param>
        private void ClickSpace(int i, int j, Graphics g)
        {
            int mineCount = 0;
            if (i - 1 >= 0 && j - 1 >= 0) //西北
            {
                if (gameMain[i - 1, j - 1] == MineGame.Empty && mine[i - 1, j - 1] != MineGame.Mine)
                {
                    mineCount = GetMineCount(i - 1, j - 1);
                    SetDrawString(mineCount, i - 1, j - 1,g);
                }
                else if (gameMain[i - 1, j - 1] != MineGame.RedFlag && mine[i - 1, j - 1] == MineGame.Mine)
                {
                    GameOver(i - 1, j - 1);
                    return;
                }
            }

            if (i - 1 >= 0)              //北方
            {
                if (gameMain[i - 1, j] == MineGame.Empty && mine[i - 1, j] != MineGame.Mine)
                {
                    mineCount = GetMineCount(i - 1, j);
                    SetDrawString(mineCount, i - 1, j, g);
                }
                else if (gameMain[i - 1, j] != MineGame.RedFlag && mine[i - 1, j] == MineGame.Mine)
                {
                    GameOver(i - 1, j); 
                    return;
                }
            }

            if (i - 1 >= 0 && j + 1 < x)//东北
            {
                if (gameMain[i - 1, j + 1] == MineGame.Empty && mine[i - 1, j + 1] != MineGame.Mine)
                {
                    mineCount = GetMineCount(i - 1, j + 1);
                    SetDrawString(mineCount, i - 1, j + 1, g);
                }
                else if (gameMain[i - 1, j + 1] != MineGame.RedFlag && mine[i - 1, j + 1] == MineGame.Mine)
                {
                    GameOver(i - 1, j + 1);
                    return; 
                }

            }

            if (j - 1 >= 0)             //西方
            {
                if (gameMain[i, j - 1] == MineGame.Empty && mine[i, j - 1] != MineGame.Mine)
                {
                    mineCount = GetMineCount(i, j - 1);
                    SetDrawString(mineCount, i, j - 1, g);
                }
                else if (gameMain[i, j - 1] != MineGame.RedFlag && mine[i, j - 1] == MineGame.Mine)
                {
                    GameOver(i, j - 1);
                    return; 
                }
            }

            if (j + 1 < x)             //东方
            {
                if (gameMain[i, j + 1] == MineGame.Empty && mine[i, j + 1] != MineGame.Mine)
                {
                    mineCount = GetMineCount(i, j + 1);
                    SetDrawString(mineCount, i, j + 1, g);
                }
                else if (gameMain[i, j + 1] != MineGame.RedFlag && mine[i, j + 1] == MineGame.Mine)
                {
                    GameOver(i, j + 1); 
                    return; 
                }
            }

            if (i + 1 < y && j - 1 >= 0)//西南
            {
                if (gameMain[i + 1, j - 1] == MineGame.Empty && mine[i + 1, j - 1] != MineGame.Mine)
                {
                    mineCount = GetMineCount(i + 1, j - 1);
                    SetDrawString(mineCount, i + 1, j - 1, g);
                }
                else if (gameMain[i + 1, j - 1] != MineGame.RedFlag && mine[i + 1, j - 1] == MineGame.Mine)
                {
                    GameOver(i + 1, j - 1); 
                    return; 
                }
            }

            if (i + 1 < y)             //南
            {
                if (gameMain[i + 1, j] == MineGame.Empty && mine[i + 1, j] != MineGame.Mine)
                {
                    mineCount = GetMineCount(i + 1, j);
                    SetDrawString(mineCount, i + 1, j, g);
                }
                else if (gameMain[i + 1, j] != MineGame.RedFlag && mine[i + 1, j] == MineGame.Mine)
                {
                    GameOver(i + 1, j);
                    return;
                }
            }

            if (i + 1 < y && j + 1 < x)//东南
            {
                if (gameMain[i + 1, j + 1] == MineGame.Empty && mine[i + 1, j + 1] != MineGame.Mine)
                {
                    mineCount = GetMineCount(i + 1, j + 1);
                    SetDrawString(mineCount, i + 1, j + 1, g);
                }
                else if (gameMain[i + 1, j + 1] != MineGame.RedFlag && mine[i + 1, j + 1] == MineGame.Mine)
                {
                    GameOver(i + 1, j + 1); 
                    return;
                }
            }
        }
        #endregion

        #region 画出当前方块周围8格的地雷总数
        /// <summary>
        /// 画出当前方块周围8格的地雷总数
        /// </summary>
        /// <param name="count">地雷个数</param>
        /// <param name="i">X轴</param>
        /// <param name="j">Y轴</param>
        private void SetDrawString(int count, int i, int j,Graphics g)
        {
            SolidBrush sb = null;
            switch (count)
            {
                case 0:
                    gameMain[i, j] = MineGame.Zero;
                    ClickSpace(i, j,g);
                    sb = new SolidBrush(Color.White);
                    break;
                case 1:
                    gameMain[i, j] = MineGame.One;
                    sb = new SolidBrush(Color.Blue);
                    break;
                case 2:
                    gameMain[i, j] = MineGame.Two;
                    sb = new SolidBrush(Color.Green);
                    break;
                case 3:
                    gameMain[i, j] = MineGame.Three;
                    sb = new SolidBrush(Color.OrangeRed);
                    break;
                case 4:
                    gameMain[i, j] = MineGame.Four;
                    sb = new SolidBrush(Color.DarkBlue);
                    break;
                case 5:
                    gameMain[i, j] = MineGame.Five;
                    sb = new SolidBrush(Color.DarkRed);
                    break;
                case 6:
                    gameMain[i, j] = MineGame.Six;
                    sb = new SolidBrush(Color.LawnGreen);
                    break;
                case 7:
                    gameMain[i, j] = MineGame.Seven;
                    sb = new SolidBrush(Color.IndianRed);
                    break;
                case 8:
                    gameMain[i, j] = MineGame.Eight;
                    sb = new SolidBrush(Color.PaleVioletRed);
                    break;
            }
            //喷绘白底
            g.FillRectangle(new SolidBrush(flipColor), someY * j + 1, someX * i + 1, someX - 1, someY - 1);
            //画出数字
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.DrawString(count.ToString(), new Font("黑体", box-5, FontStyle.Bold), sb, new PointF(box * j + 2, box * i + 1));
        }
        #endregion

        #region 游戏结束时,画出当前方块周围8格的地雷总数
        /// <summary>
        /// 画出当前方块周围8格的地雷总数
        /// </summary>
        /// <param name="count">地雷个数</param>
        /// <param name="i">X轴</param>
        /// <param name="j">Y轴</param>
        private void GameOverDrawString(int count, int i, int j,Graphics g)
        {
            SolidBrush sb = null;
            switch (count)
            {
                case 0:
                    gameMain[i, j] = MineGame.Zero;
                    sb = new SolidBrush(Color.White);
                    break;
                case 1:
                    gameMain[i, j] = MineGame.One;
                    sb = new SolidBrush(Color.Blue);
                    break;
                case 2:
                    gameMain[i, j] = MineGame.Two;
                    sb = new SolidBrush(Color.Green);
                    break;
                case 3:
                    gameMain[i, j] = MineGame.Three;
                    sb = new SolidBrush(Color.OrangeRed);
                    break;
                case 4:
                    gameMain[i, j] = MineGame.Four;
                    sb = new SolidBrush(Color.DarkBlue);
                    break;
                case 5:
                    gameMain[i, j] = MineGame.Five;
                    sb = new SolidBrush(Color.DarkRed);
                    break;
                case 6:
                    gameMain[i, j] = MineGame.Six;
                    sb = new SolidBrush(Color.LawnGreen);
                    break;
                case 7:
                    gameMain[i, j] = MineGame.Seven;
                    sb = new SolidBrush(Color.IndianRed);
                    break;
                case 8:
                    gameMain[i, j] = MineGame.Eight;
                    sb = new SolidBrush(Color.PaleVioletRed);
                    break;
            }
            //喷绘白底
            g.FillRectangle(new SolidBrush(flipColor), someY * j + 1, someX * i + 1, someX - 1, someY - 1);
            //画出数字
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.DrawString(count.ToString(), new Font("黑体", box - 5, FontStyle.Bold), sb, new PointF(box * j + 2, box * i + 1));
        }
        #endregion

        #region 窗体加载
        public void Form1_Load(object sender, EventArgs e)
        {
            FirstRunGame();
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); //双缓冲
        }
        #endregion

        #region 游戏选项
        private void tsmiOption_Click(object sender, EventArgs e)
        {
            frmOption fo = new frmOption();
            fo.ShowDialog();
            FirstRunGame();
        }
        #endregion

        #region 标记完红旗后双击数字
        /// <summary>
        /// 双击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void panelMain_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            int i = (e.Y - 1) / someX;//当前行
            int j = (e.X - 1) / someY;//当前列
            bool isRight = false;
            if (e.Button == MouseButtons.Left && e.Clicks == 2)
            {
                if (gameMain[i, j] == MineGame.Empty)
                {
                    return;
                }

                int mineCount = GetgameMainCount(i, j);                                 //计算有几面红旗了      
                switch (gameMain[i, j])                                                 //获取当前点击的格子数字是几
                {                                                                       //如果标记的地雷大于或者等于红旗数了
                    case MineGame.One:                                                  //就翻开除了标记了红旗以外的所有格子
                        if (mineCount >= 1)
                        {
                            isRight = true;
                        }
                        break;
                    case MineGame.Two:
                        if (mineCount >= 2)
                        {
                            isRight = true;
                        }
                        break;
                    case MineGame.Three:
                        if (mineCount >= 3)
                        {
                            isRight = true;
                        }
                        break;
                    case MineGame.Four:
                        if (mineCount >= 4)
                        {
                            isRight = true;
                        }
                        break;
                    case MineGame.Five:
                        if (mineCount >= 5)
                        {
                            isRight = true;
                        }
                        break;
                    case MineGame.Six:
                        if (mineCount >= 6)
                        {
                            isRight = true;
                        }
                        break;
                    case MineGame.Seven:
                        if (mineCount >= 7)
                        {
                            isRight = true;
                        }
                        break;
                    case MineGame.Eight:
                        if (mineCount >= 8)
                        {
                            isRight = true;
                        }
                        break;
                }
                Graphics g = panelMain.CreateGraphics();
                if (isRight) 
                {
                    ClickSpace(i, j, g);
                }
                g.Dispose();
                Judge();
            }
        }
        #endregion

        #region 计时器
        private void timerTime_Tick(object sender, EventArgs e)
        {
            time = time + 1;
            this.lblTimeCount.Text = time.ToString();
        }
        #endregion

        #region 游戏结束
        public void GameOver(int a,int b)
        {
            playAudio("boom.mp3");
            timerTime.Enabled = false;
            Graphics g = panelMain.CreateGraphics();
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;//高质量显示图片
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < x; j++)
                {
                    if (gameMain[i, j] == MineGame.RedFlag)
                    {
                        g.DrawImage((Bitmap)manager.GetObject("redflag"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                        if (gameMain[i, j] == MineGame.RedFlag && mine[i, j] != MineGame.Mine) 
                        {
                            g.DrawImage((Bitmap)manager.GetObject("Explode1"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                        }
                    }
                    else if (mine[i, j] == MineGame.Mine)
                    {
                        g.DrawImage((Bitmap)manager.GetObject("mine"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                    }
                    else
                    {
                        GameOverDrawString(GetMineCount(i, j), i, j, g);
                    }
                }
                //System.Threading.Thread.Sleep(30);
            }
            g.FillRectangle(new SolidBrush(Color.Yellow), someY * b + 1, someX * a + 1, someX - 1, someY - 1);
            g.DrawImage((Bitmap)manager.GetObject("mine"), someX * b + 5, someY * a + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
            g.DrawImage((Bitmap)manager.GetObject("Explode1"), someX * b + 5, someY * a + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
            g.Dispose();
            isGameOver = true;
            fromGameOver gmae = new fromGameOver("Failure",this.lblTimeCount.Text);
            gmae.ShowDialog();
            if (gameStartType == "2")
            {
                ReGameStart();
            }
            else if (gameStartType == "1")
            {
                GameStart();
            }
        }
        #endregion

        #region 游戏失败或通关的判断
        public bool Success() 
        {
            int MineSuccess = 0;
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < x; j++)
                {
                    if (mine[i, j] == MineGame.Mine && gameMain[i, j] == MineGame.RedFlag) 
                    {
                        MineSuccess++;
                    } 
                }
            }
            return MineSuccess == mineCount;
        }

        public int GetFlip()
        {
            int black = 0;
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < x; j++)
                {
                    if (gameMain[i, j] == MineGame.Empty)
                    {
                        black++;
                    }
                }
            }
            return black;
        }

        public void Judge() 
        {
            if (int.Parse(this.lblmine.Text) == 0)
            {
                if (GetFlip() <= 0)
                {
                    if (Success())
                    {
                        fromGameOver gmae = new fromGameOver("Success", this.lblTimeCount.Text);
                        gmae.ShowDialog();
                        if (gameStartType == "2")
                        {
                            ReGameStart();
                        }
                        else if (gameStartType == "1")
                        {
                            GameStart();
                        }
                    }
                }
            }
        }
        #endregion

        #region 将数据置为初始状态
        /// <summary>
        ///  将数据置为初始状态
        /// </summary>
        public void ResetPage() 
        {
            time = 0;
            isGameOver = false;
            timerTime.Enabled = true;
            lblmine.Text = mineCount.ToString();
            BrushGameMain();           
        }
        #endregion

        #region 读取配置，初始化游戏信息
        /// <summary>
        /// 读取配置，初始化游戏信息
        /// </summary>
        public void ReadConfig() 
        {
            List<MyConfig> list = XmlHelper.XmlDeserializeFromFile<List<MyConfig>>(XmlFileName, Encoding.UTF8);
            //X轴方块个数
            x = int.Parse(list[0].Width);
            //Y轴方块个数
            y = int.Parse(list[0].Height);
            //地雷个数
            mineCount = int.Parse(list[0].MineCount);
            if (mineCount < 20)
            {
                blankCount = 1;
            }
            if (mineCount <= 40) 
            {
                blankCount = 2;
            }
            else if (mineCount <= 99)
            {
                blankCount = 3;
            }
            else 
            {
                blankCount = 4;
            }
            //方块的长宽
            box = int.Parse(list[0].Box);
            //是否播放声音
            playSound = list[0].PlaySound == "1" ? true : false;
            //是否允许问号
            isQuestion = list[0].IsQuestion == "1" ? true : false;
            //是否允许随意点击3次
            isFristPaly = list[0].FirstPlay == "1" ? true : false;
            //是否允许翻开3个空白格子
            isNewPaly = list[0].NewPlay == "1" ? true : false;
            //窗体宽
            this.Width = x * box + 32;
            //窗体高
            this.Height = y * box + 140;
            //游戏区宽
            panelMain.Width = x * box + 1;
            //游戏区高
            panelMain.Height = y * box + 1;
            //游戏区方块翻开前背景色
            backColor = ColorTranslator.FromHtml(list[0].BackColor);
            //游戏区方块翻开后背景颜色
            flipColor = ColorTranslator.FromHtml(list[0].FlipColor);
            someX = panelMain.Height / y;
            someY = panelMain.Width / x;
            isFirstRun = true;
            mine = new MineGame[y, x];
            gameMain = new MineGame[y, x];
            panelMain.BackColor = backColor;
        }
        #endregion

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            GameStart();
        }

        private void panelMain_MouseUp(object sender, MouseEventArgs e)
        {
            MouseButtonsLeft = false;
            MouseButtonsRight = false;
        }

        #region 播放声音
        /// <summary>
        /// 播放声音的方法
        /// </summary>
        /// <param name="url">音频文件的路径</param>
        private void playAudio(string url)
        {
            if (playSound)
            {
                wmp.URL = url;
                wmp.controls.play();
            }
        }
        #endregion

        #region 鼠标按下事件
        private void panelMain_MouseDown(object sender, MouseEventArgs e)
        {
            Graphics g = panelMain.CreateGraphics();
            int i = (e.Y - 1) / someX;//当前行
            int j = (e.X - 1) / someY;//当前列
            if (e.Button == MouseButtons.Left && e.Clicks == 1)
            {
                MouseButtonsLeft = true;
                //如果是红旗,什么都不执行,直接返回
                if (gameMain[i, j] == MineGame.RedFlag)
                {
                    return;
                }

                //如果是地雷,爆炸,游戏结束
                if (mine[i, j] == MineGame.Mine)
                {
                    gameMain[i, j] = MineGame.Explode;
                    GameOver(i,j);
                    return;
                }

                //如果不是空,播放错误提示,返回
                if (gameMain[i, j] != MineGame.Empty)
                {
                    playAudio("Error.wav");
                    return;
                }
                //播放点击音效
                playAudio("Click.wav");
                //计算地雷,然后画出数字
                SetDrawString(GetMineCount(i, j), i, j,g);
            }
            else if (e.Button == MouseButtons.Right && e.Clicks == 1)
            {
                MouseButtonsRight = true;
                //如果右击的是空白,返回
                if (gameMain[i, j] != MineGame.Empty && gameMain[i, j] != MineGame.RedFlag)
                {
                    return;
                }
                playAudio("Click2.wav");
                if (gameMain[i, j] == MineGame.RedFlag)
                {
                    g.FillRectangle(new SolidBrush(panelMain.BackColor), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);
                    gameMain[i, j] = MineGame.Empty;
                    lblmine.Text = (int.Parse(lblmine.Text) + 1).ToString();
                }
                else
                {
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;//高质量显示图片
                    g.DrawImage((Bitmap)manager.GetObject("redflag"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                    gameMain[i, j] = MineGame.RedFlag;
                    lblmine.Text = (int.Parse(lblmine.Text) - 1).ToString();
                }
            }
            g.Dispose();
            Judge();
        }
        #endregion

        #region 鼠标移动事件
        private void panelMain_MouseMove(object sender, MouseEventArgs e)
        {
            if (MouseButtonsLeft && MouseButtonsRight)
            {
                Graphics g = panelMain.CreateGraphics();
                int i = (e.Y - 1) / someX;//当前行
                int j = (e.X - 1) / someY;//当前列
                if (i != lastOverX || j != lastOverY)
                {
                    EachBox(i, j, Color.Moccasin);
                    //ReturnShape(i, j);


                    //g.DrawRectangle(new Pen(panelMain.BackColor, 1), box * lastOverY + 2, box * lastOverX + 2, box - 4, box - 4);
                    //g.DrawRectangle(new Pen(Color.Red, 1), box * j + 2, box * i + 2, box - 4, box - 4);//在当前方格处绘制红色标记
                    lastOverX = i;//当前行赋值给上次的行
                    lastOverY = j;
                }
                g.Dispose();
            }
        }
        #endregion

        #region 以单击的方块为中心，向周围8块刷白底
        private void BrushAround(int i, int j, SolidBrush sb,int mineCount, Graphics g,Color color) 
        {
            g.FillRectangle(new SolidBrush(color), someY * j + 1, someX * i + 1, someX - 1, someY - 1);
            //画出数字
            if (mineCount >= 0)
            {
                g.DrawString(mineCount.ToString(), new Font("黑体", box - 5, FontStyle.Bold), sb, new PointF(box * j + 2, box * i + 1));
            }
            else if (mineCount == -1)
            {
                g.DrawImage((Bitmap)manager.GetObject("redflag"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
            }
        }

        private void EachBox(int i, int j, Color c) 
        {
            Graphics g = panelMain.CreateGraphics();
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;   //高质量显示数字
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;                     //高质量显示图片

            int mineCount = 0;
            //BrushAround(i, j, GetSolidBrushColor(gameMain[i, j], out mineCount), mineCount, g);
            if (i - 1 >= 0)
            {
                BrushAround(i - 1, j, GetSolidBrushColor(gameMain[i - 1, j], out mineCount), mineCount, g,c);
            }

            if (i - 1 >= 0 && j - 1 >= 0)
            {
                BrushAround(i - 1, j - 1, GetSolidBrushColor(gameMain[i - 1, j - 1], out mineCount), mineCount, g, c);
            }

            if (j - 1 >= 0)
            {
                BrushAround(i, j - 1, GetSolidBrushColor(gameMain[i, j - 1], out mineCount), mineCount, g, c);
            }

            if (i + 1 < y && j - 1 >= 0)
            {
                BrushAround(i + 1, j - 1, GetSolidBrushColor(gameMain[i + 1, j - 1], out mineCount), mineCount, g, c);
            }

            if (i + 1 < y)
            {
                BrushAround(i + 1, j, GetSolidBrushColor(gameMain[i + 1, j], out mineCount), mineCount, g, c);
            }

            if (i - 1 >= 0 && j + 1 < x)
            {
                BrushAround(i - 1, j + 1, GetSolidBrushColor(gameMain[i - 1, j + 1], out mineCount), mineCount, g, c);
            }

            if (j + 1 < x)
            {
                BrushAround(i, j + 1, GetSolidBrushColor(gameMain[i, j + 1], out mineCount), mineCount, g, c);
            }

            if (i + 1 < y && j + 1 < x)
            {
                BrushAround(i + 1, j + 1, GetSolidBrushColor(gameMain[i + 1, j + 1], out mineCount), mineCount, g, c);
            }
            g.Dispose();
        }
        #endregion

        #region 获取点击周围八格的颜色
        /// <summary>
        /// 提高重复使用
        /// </summary>
        /// <param name="mg">枚举类型</param>
        /// <param name="mineCount"></param>
        /// <returns></returns>
        private SolidBrush GetSolidBrushColor(MineGame mg,out int mineCount) 
        {
            SolidBrush sb = null;
            mineCount = 0;
            switch (mg)
            {
                case MineGame.RedFlag:
                    mineCount = -1;
                    sb = new SolidBrush(Color.SkyBlue);
                    break;
                case MineGame.Empty:
                    mineCount = -2;
                    sb = new SolidBrush(Color.SkyBlue);
                    break;
                case MineGame.Zero:
                    mineCount = 0;
                    sb = new SolidBrush(Color.Moccasin);
                    break;
                case MineGame.One:
                    mineCount = 1;
                    sb = new SolidBrush(Color.Blue);
                    break;
                case MineGame.Two:
                    mineCount = 2;
                    sb = new SolidBrush(Color.Green);
                    break;
                case MineGame.Three:
                    mineCount = 3;
                    sb = new SolidBrush(Color.OrangeRed);
                    break;
                case MineGame.Four:
                    mineCount = 4;
                    sb = new SolidBrush(Color.DarkBlue);
                    break;
                case MineGame.Five:
                    mineCount = 5;
                    sb = new SolidBrush(Color.DarkRed);
                    break;
                case MineGame.Six:
                    mineCount = 6;
                    sb = new SolidBrush(Color.LawnGreen);
                    break;
                case MineGame.Seven:
                    mineCount = 7;
                    sb = new SolidBrush(Color.IndianRed);
                    break;
                case MineGame.Eight:
                    mineCount = 8;
                    sb = new SolidBrush(Color.PaleVioletRed);
                    break;
            }
            return sb;
        }
        #endregion

        private void ReturnShape(int i,int j) 
        {
            SolidBrush sb = null;
            Graphics g = panelMain.CreateGraphics();
            for (int c = 0; c < lastBoxColor.Count; c++)
            {
                if ((MineGame)lastBoxColor[c] == MineGame.RedFlag)
                {
                    g.DrawImage((Bitmap)manager.GetObject("redflag"), someX * j + 5, someY * i + 5, someX - 5 - 5, someY - 5 - 5);//将图片画在游戏区
                }
                
                if (sb == null)
                {
                    continue;
                }
                g.FillRectangle(sb, someY * j + 1, someX * i + 1, someX - 1, someY - 1);
                g.Dispose();
            }
        }
    }
}
